/***2024-12-31 迷途小羔羊
* 用于编写索敌行为
*/
namespace ghost
{
    export class B_FindAttack extends BehaviorBase
    {
        /**恢复攻击行为执行间隔*/protected _findAtkTargetInterval:number;
		/**上一次攻击行为停顿的时间戳*/protected _findAtkTargetTime:number;
        protected _speed:number;
		protected _findPathToTarget:boolean;
        constructor(ai:AIBase)
        {
            super(ai);
            let s = this;
            s._speed = NaN;
        }
        public exc(t:number):void
		{
            super.exc(t);
            let r:GameRole;
            let s = this;
            r = s._role;
			
			if(t - s._findAtkTargetTime < s._findAtkTargetInterval)return;
			if(s._findPathToTarget)return;
			let target:GameRole;
			let targets:GameRole[];			
			if(r._isDead)return;
			if(r._skillList.length == 0)return;
			let skill:ISkillData;
			targets = r.getAtkTarget();
			target = targets[0];
			skill = r.getProritySkill(target);	
			if(skill == null)
				return;			
			if(!r.inMyTerritoryRange())//我在安全区或者我离开了领地范围
			{
				// r.inRangeFlag = 1;
				r.setAtkTarget(null);
				target = null;
			}
			else
			{
								
				if(target == null || !r.canAttack(target,skill.skillCfg.campFlag))
				{//查询最近目标靠近					
					let arr:GameRole[];
					arr = r.findEnemy(skill);
					r.setAtkTarget(arr);
					target = r._targetRoles[0];				
				}
			}
			
			//攻击目标
			if(target)
			{
				r.stopFindPath();		
				if(r._hasEnemyInRange)
				{
					if(!r.inBattleState)		
					{
						//从脱战进入战斗状态，重置前置cd
						// r.resetPreCD(t);
						r.inBattleState = true;
						// r.inResourceState = false;
					}
				}								
				if(s.attackEnemy(r._targetRoles, false))									
					return;				
				r.resetTargetDir(target);
				let toClosed:boolean;
				let dis:number,atkDis:number;
				if(r._camp == CampType.CAMP_1)
				{
					dis = target._bodyMinDis;
					toClosed = dis*dis > PositionUtil.calculateDistance2(r.absX,r.absY,target.absX,target.absY);
					if(toClosed)//距离太近
					{
						atkDis = r.getAttackRangeMax(skill);
						if(atkDis > dis)//攻击距离大于受击范围,允许反方向移动，避免近距离攻击
						{
							r._targetAngle = r._targetAngle + Math.PI;
							r._targetDirection = map2D.DirectionType.getDirectorSts(r._targetAngle);
						}					
					}
				}				
				//前往攻击目标附近
				let moveState:MoveState;
				moveState = r.moveDir(r._targetAngle, s._speed, toClosed?target:null);
				if(moveState.result < MoveResult.PASS)
				{	
					if(r._moveStopRole)
					{
						if(r._moveStopRole._camp == target._camp)
						{						
							//遭遇目标
							if(r._moveStopRole == target)
							{
								if(s._speed <= 1)
								{
									s._findAtkTargetTime = 0;
                                    s.behaviorOut(s, BehaviorEnum.DETOUR);									
								}
								else
								{//降低移动速度以确保能排除碰撞检测的干扰而更小步长接近目标进行攻击
									s._speed = Math.max(1,r.speed >> 1);
									r.moveDir(r._targetAngle, s._speed, toClosed?target:null);
									if(s.attackEnemy(r._targetRoles, false))
										return;	
								}							
								return;
							}
							//遭遇的是新目标,标记为目标
							r.setAtkTarget([r._moveStopRole]);
							return;
						}						
					}				
					
					//行走遭遇障碍，设置AI停顿
					if(s._findAtkTargetTime > 0)
					{
						s._findAtkTargetTime = 0;						
						s.detour(s._role, target, moveState);
						return;
					}
					s._findAtkTargetTime = t;
					return;
				}				
				let speed:number = r.speed*0.5;
				if(moveState.distanceX() < speed && moveState.distanceY() < speed)//移动步长太短，直接绕路
				{
					s._findAtkTargetTime = 0;
					s.detour(s._role, target, moveState);
					// s.behaviorOut(s, BehaviorEnum.DETOUR);
					return;
				}
				return;
			}
			
			r._lastSkillFailList[skill.skillId] = t;//记录技能查询目标失败时间，下次延后使用			
			// let nothingToDo:boolean = (4 & r.inRangeFlag) == 0;//附近不存在可针对释放技能的敌人
			//当前战斗状态，找不到目标
			// if(r.inResourceState || r.inBattleState)
			// {	
			// 	if(nothingToDo)
            //         s.behaviorOut(s, BehaviorEnum.DETACHMENT);
			// }				
			// else if(r.canPatrol)
			// {				
            //     s.behaviorOut(s, BehaviorEnum.PATROL);				
			// }			
			// else 
			if(!r._targetMove)
			{				
				if(r.sts != StsType.STAND)
					r.resetSts();				
			}			
        }
		private detour(r:GameRole, target:GameRole, moveState:MoveState):void
		{
			let s = this;
			//尝试寻路过去
			if(moveState.isXOrYNotChange())
			{
				let tarX:number,tarY:number;
				tarX = target.absX - 100;
				tarY = target.absY - 100;
				if(!r._scene.isBarrier(tarX, tarY))
				{
					r.findPathTo(tarX, tarY, r.speed, (code:number, msg:string)=>{							
						s._findPathToTarget = false;
					});
				}	
			}
			else
				s.behaviorOut(s, BehaviorEnum.DETOUR);
		}

        /**攻击目标
		 * @param targets 目标角色
		 * @param absAngle 是否朝向使用绝对准确的角度，默认false		 
		 * @param findBest 是否释放技能时重新选择最佳的攻击目标
		 * @param useSkill 指定技能攻击
		 * @return 如不在攻击范围，返回false，否则true
		*/
		protected attackEnemy(targets:GameRole[], absAngle:boolean = false, findBest:boolean=true, useSkill:ISkillData=null):boolean
		{
			let s= this;	
            let r:GameRole;
            r = s._role;
			if(r.sts >= StsType.ATTACK)return true;
			if(useSkill)						
				return s.attackEnemyBySkill(targets, absAngle, findBest, useSkill);			
			
			//判断所有技能是否存在攻击范围内且冷却已经好了的
			let skill:ISkillData;
			let i:number,len:number;				
			len = r._skillList.length;
			for(i=0;i<len;++i)
			{
				skill = r._skillList[i];
				if(skill.skillCfg.priority == 0)
					continue;
				if(r.isCDOk(skill))
				{
					if(s.attackEnemyBySkill(targets, absAngle, false, skill))						
						return true;
				}
			}			
			return false;
		}

        protected attackEnemyBySkill(targets:GameRole[], absAngle:boolean = false, findBest:boolean=true, skill:ISkillData=null):boolean
		{
			let s= this;
			let tarAngle:number,direction:number;	
			let bestTargets:GameRole[];			
			let maxRange:number;
			let skillCfg:SkillCfg;
            let r:GameRole;
            r = s._role;
			skillCfg = skill.skillCfg;
			// if(skill.skillCfg.isSkill && r.buffValues[BuffEType.SLIENT])//沉默无法释放技能
			// 	return;
			// if(skill.skillCfg.isCommonAtk && r.buffValues[BuffEType.DISARM])//缴械无法普攻
			// 	return;
			maxRange = r.getAttackRangeMax(skill);			
			//放技能时允许还要重新查找最佳对象
			if(findBest)
			{
				bestTargets = r.findEnemy(skill);								
				bestTargets = r.filterInMaxAtkRange(bestTargets, maxRange);
				if(bestTargets.length == 0)
					return false;
				targets = bestTargets;						
			}
			else
			{
				targets = r.filterInMaxAtkRange(targets, maxRange);
				if(targets.length == 0)
					return false;
			}
			
			let target:GameRole;			
			targets.length = Math.min(targets.length, skillCfg.num);
					
			target = targets[0];
			if(target == null)							
				return false;
			r.setAtkTarget(targets);
			if(r == target)
				direction = -1;
			else
			{
				tarAngle = absAngle?PositionUtil.calculateAngle(target.absX,target.absY,r.absX,r.absY):PositionUtil.calculateAngle(target.col,target.row,r.col,r.row);
				direction = map2D.DirectionType.getDirectorSts(tarAngle);	
				//上下方向时候做校正，根据目标位置判断方向	
				if(direction == map2D.DirectionType.UP || direction == map2D.DirectionType.DOWN){
					if(target.absX == r.absX){
						//x坐标相等时取y坐标判断，上左下右
						direction = target.absY > r.absY ? map2D.DirectionType.RIGHT : map2D.DirectionType.LEFT;
					}
					else{
						direction = target.absX > r.absX ? map2D.DirectionType.RIGHT : map2D.DirectionType.LEFT;
					}
				}		
			}			
			r.operSkill(skill,direction);	
			return true;
		}
        public resetState(): void {
            super.resetState();
            let s = this;
            s._findAtkTargetInterval = 500;
			s._findAtkTargetTime = 0;
        }
    }
}